import { spawn } from "child_process";
import shell from "shelljs";
 class GitTools {
  /**
   * 构造函数
   * @param {String} cwd 工作目录
   * */
  constructor(cwd, project) {
    this.cwd = cwd;
    this.result = [];
    this.project = project;
  }

  /**
   * git add
   * */
  add() {
    var params = ["add", "."];

    return this.startChildProcess("git", params);
  }

  /**
   * git commit
   * @param {String} remark 备注信息
   * */
  commit(remark = "nodejs run git 默认备注信息") {
    var params = ["commit", "-m", remark];

    return this.startChildProcess("git", params);
  }

  /**
   * 是否存在分支
   * @param branch
   */
  async exitsBranch(branch){
    let params=['show-branch',branch]
    let res=await this.startChildProcess('git',params)
    console.log("是否存在",res)
    return res;
  }

  /**
   * 是否合并
   * @param branch
   * @returns {Promise<unknown>}
   */
  async exitsMerge(branch){
    let params=['branch','--merged']

    let res=await this.startChildProcess('git',params)
    console.log("是否合并",res)
    return res;
  }
  /**
   * git push
   * @param {String} branch 分支名
   * */
  push(branch) {
    if (!branch) {
      throw "please input branch name !";
    }

    var params = ["push", "origin", branch];

    return this.startChildProcess("git", params);
  }
  merge(branch) {
    var params = ["merge", branch];

    return this.startChildProcess("git", params);
  }
  fetch() {
    var params = ["fetch"];

    return this.startChildProcess("git", params);
  }
  delete(branch){
    var params = ["branch", "-d", branch];

    return this.startChildProcess("git", params);
  }
  /**
   * git checkout
   * @param {String} branch 分支名
   * */
  checkout(branch) {
    if (!branch) {
      throw "please input branch name !";
    }

    var params = ["checkout", branch];
    return new Promise(async (resolve, reject) => {
      let branchInfo = await this.branch();

      // 当前分支不为目标分支并且存在修改跳出
      if (branch != branchInfo.current) {
        var isChange = await this.status();
        if (isChange) {
          reject("当前有修改未提交无法切换分支");
          return;
        }
        // 切分支
        await this.startChildProcess("git", params);
        resolve();
      } else {
        resolve();
      }
    });
  }

  /**
   * git branch
   * @return {String} current 当前分支
   * @return {Array} branchs 当前本地所有分支
   * */
  async branch() {
    var params = ["branch"];
    var result = await this.startChildProcess("git", params);
    var current = "";
    var branchs = result
      .split("\n")
      .map((item) => {
        var reg = new RegExp(/\*/g);
        if (reg.test(item)) {
          item = item.replace(reg, "");
          current = item.trim();
        }
        return item.trim();
      })
      .filter((item) => item);

    return {
      current,
      branchs,
    };
  }
  /**
   * git pull
   * @param {String} branch 分支名
   * */
  pull(branch) {
    if (!branch) {
      throw "please input branch name !";
    }

    var params = ["pull", "origin", branch];

    return this.startChildProcess("git", params);
  }
  async gitLog(branch, type, commitId) {
    let params = ["rev-parse", "HEAD"];
    if (type === 1) {
      params = ["rev-parse", "HEAD"];
    } else {
      params = ["branch", "-a", "--contains", commitId];
    }
    let res = await this.startChildProcess("git", params);
    console.log("res", res, commitId);
    return res;
  }
  /**
   * git status
   * @return {Boolean} 是否存在修改
   * */
  async status() {
    try {
      var params = ["status", "-s"];
      let result = await this.startChildProcess("git", params);
      return result ? true : false;
    } catch (err) {
      console.error(err);
    }

    return false;
  }

  async diff() {
    try {
      var params = ["diff", "--check"];
      let result = await this.startChildProcess("git", params);
      return result ? true : false;
    } catch (err) {
      console.error(err);
    }

    return false;
  }
  /**
   * 开启子进程
   * @param {String} command  命令 (git/node...)
   * @param {Array} params 参数
   * */
  startChildProcess(command, params) {
    return new Promise((resolve, reject) => {
      let process = spawn(command, params, {
        cwd: this.cwd,
      });
      console.log("params", params, this.cwd);
      let logMessage = `${command} ${params[0]}`;
      let cmdMessage = "";

      process.stdout.on("data", (data) => {
        if (!data) {
          resolve(`error`);
        } else {
          cmdMessage = data.toString();
        }
      });
      process.on("error", (message) => {
        console.log("error", message);
      });
      process.on("close", (data, e1, e2, e3) => {
        console.log(`${logMessage} close ---`, this.cwd);
        if (data) {
          resolve("error");
        } else {
          console.log(`${logMessage} success !`);
          resolve(cmdMessage);
        }
      });
      process.on("unhandledRejection", (error) => {
        reject(this.project);
      });
    });
  }
  /**
   * 自动上传
   * @param {String} remark 备注的信息
   * @param {String} branch 目标分支
   * */
  async autoUpload(remark, branch) {
    try {
      // git checkout branch
      await this.checkout(branch);

      // git pull branch
      await this.pull(branch);

      // git add .
      await this.add();

      // git status -s
      var isChange = await this.status();

      if (isChange) {
        // git commit -m remark
        await this.commit(remark);

        // git push branch
        await this.push(branch);
      } else {
        console.log("not have to upload");
      }

      console.log("auto upload success !");

      return true;
    } catch (err) {
      console.error(err);
    }

    console.log("auto upload error !");
    return false;
  }
};
 export default GitTools
